package org.example.test;

import java.util.concurrent.locks.ReentrantLock;

public class LockInterruptiblyExample {

    private static final ReentrantLock lock = new ReentrantLock();


    /**
     * reentrantlock中lockInterruptibly方法的简单示例
     * 代码解释：
     * 下述代码创建了一个 ReentrantLock 对象 lock。
     * 线程 thread1 首先调用 lockInterruptibly() 方法获取锁，获取成功后会持有锁 5 秒钟。
     * 线程 thread2 随后调用 lockInterruptibly() 方法尝试获取锁，由于 thread1 持有锁，thread2 会进入等待状态。
     * 主线程在启动 thread1 和 thread2 一秒钟后，调用 thread2.interrupt() 中断 thread2。
     * 由于 thread2 正在使用 lockInterruptibly() 等待锁，它会立即响应中断，抛出 InterruptedException，
     * 打印出 "Thread 2 was interrupted while waiting for the lock"。
     * 注：这里需要强调的是，reentrantlock对象必须通过调用lockInterruptibly()方法的方式加锁才可以实现中断加锁的操作，
     * 而且中断加锁的操作是由线程发起，而不是由reentrantlock对象发起。
     *
     * @param args 主函数入参
     */
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            try {
                lock.lockInterruptibly();
                try {
                    System.out.println("Thread 1 acquired the lock");
                    // 模拟长时间持有锁
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    System.out.println("Thread 1 was interrupted while holding the lock");
                } finally {
                    lock.unlock();
                }
            } catch (InterruptedException e) {
                System.out.println("Thread 1 was interrupted while waiting for the lock");
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                lock.lockInterruptibly();
                try {
                    System.out.println("Thread 2 acquired the lock");
                } finally {
                    lock.unlock();
                }
            } catch (InterruptedException e) {
                System.out.println("Thread 2 was interrupted while waiting for the lock");
            }
        });

        thread1.start();
        thread2.start();

        // 一段时间后中断线程 2
        try {
            Thread.sleep(1000);
            thread2.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
